/**
* @author TDSoft
*
* La clase GestorUniversidad se encarga de gestionar la persistencia de los datos relativos a Universidades
*
* @see Universidad
*/

package edu.uoc.tds.pec4.server.bbdd;


import edu.uoc.tds.pec4.common.RemotoInterface;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.PreparedStatement;
import edu.uoc.tds.pec4.exception.UniversidadNoExisteException;
import edu.uoc.tds.pec4.i18n.GestorIdiomas;
import edu.uoc.tds.pec4.model.Universidad;
import java.rmi.RemoteException;
import java.util.ArrayList;
import java.util.List;

public class GestorUniversidad {
    
    //Atributo para gestionar el servicio de acceso remoto
    RemotoInterface remoto;
    
    /**
     * Constructor con parámetros de la clase GestorUniversidad.
     * Crea una instancia de GestorUniversidad.
     * {pre: se recibe como parametro la instancia del servidor remoto}
     * {post: asigna el servidor remoto a la instancia de GestorUniversidad que se va utilizar en toda la clase}
     */
    public GestorUniversidad(RemotoInterface remoto){
        this.remoto = remoto;
    }

    /**
     * Método para obtener la instancia de Universidad que corresponde a un identificador de universidad
     * {pre: id_universidad el identificador de universidad}
     * {post: una instancia de Universidad correspondiente al id_universidad pasado por parámetro}
     * @param id_universidad de tipo entero hace referencia al identificador de universidad
     */
    public Universidad getUniversidad(int id_universidad) throws RemoteException{
	
        Universidad universidad = null;
        String sqlString = null;
        //Establecemos la sentencia para obtener los datos asociados a ese id_universidad
	sqlString = "SELECT id_universidad,nombre_universidad "
                    + "FROM " + this.remoto.getSchema() + ".universidad "
                    + "WHERE id_universidad = ?;";
        PreparedStatement preparedStatement = null;
        ResultSet resultSet = null;

	try{
            preparedStatement = this.remoto.getConexion().prepareStatement(sqlString);
            preparedStatement.setInt(1, id_universidad);
            resultSet = preparedStatement.executeQuery();

            //Si la consulta devuelve un dato generaremos la instancia correspondiente que devolverá el método
            if(resultSet.next()){
                String nombre = null;
		nombre = resultSet.getString("nombre_universidad");
                //instanciamos la clase Universidad con los datos recuperados de la BBDD
                universidad = new Universidad(id_universidad, nombre);
            }
            else{
                //Lanzamos excepción si no se encuentra en la BBDD ese id_universidad para ninguna universidad
                throw new UniversidadNoExisteException(GestorIdiomas.getMessage("error.iduniversidad.no.existe"));
            }
        }
        /** Capturamos excepción no se encuentre el id_universidad buscado*/
        catch(UniversidadNoExisteException exc){
           throw new RemoteException(exc.getMessage());
        }
        /** Capturamos el error en el acceso a la BBDD */
        catch (SQLException exc) {
             throw new RemoteException(GestorIdiomas.getMessage("error.gestorbbdd.bbdd"));
        }
        /** Capturamos excepción de carácter general*/
        catch (Exception exc) {
            throw new RemoteException(GestorIdiomas.getMessage("error.general"));
        }
        /** En cualquier caso ejecutaremos el siguiente código*/
        finally {
            try {
		resultSet.close();
                preparedStatement.close();
            }
            /** Capturamos excepción de carácter general*/
            catch (Exception exc) {
                throw new RemoteException(GestorIdiomas.getMessage("error.general"));
            }
        }

        return universidad;
    }
    
    /**
     * Método para obtener el identificador de Universidad que corresponde a un nombre de universidad
     * {pre: nombre_universidad el nombre de universidad}
     * {post: el identificador de Universidad correspondiente al nombre_universidad pasado por parámetro}
     * @param nombre_universidad hace referencia al nombre de universidad
     */
    public int getIdUniversidad(String nombre_universidad) throws RemoteException{
	
        int id_universidad = 0;
        String sqlString = null;
        //Establecemos la sentencia para obtener los datos asociados a ese nombre de universidad
	sqlString = "SELECT id_universidad "
                    + "FROM " + this.remoto.getSchema() + ".universidad "
                    + "WHERE nombre_universidad = ?;";
        PreparedStatement preparedStatement = null;
        ResultSet resultSet = null;
        
	//Capturaremos la excepcion en caso de error
        try{
            preparedStatement = this.remoto.getConexion().prepareStatement(sqlString);
            preparedStatement.setString(1, nombre_universidad);
            resultSet = preparedStatement.executeQuery();

            //Si la consulta devuelve un dato lo almacenamos en la variable que devolverá el método
            if(resultSet.next()){
                id_universidad = resultSet.getInt("id_universidad");
            }
            else{
                //Lanzamos excepción si no se encuentra en la BBDD ese id_universidad para el nombre de universidad
                throw new UniversidadNoExisteException(GestorIdiomas.getMessage("error.universidad.no.existe"));
            }
        }
        /** Capturamos excepción no se encuentre la universidad buscada*/
        catch(UniversidadNoExisteException exc){
           throw new RemoteException(exc.getMessage());
        }
        /** Capturamos el error en el acceso a la BBDD */
        catch (SQLException exc) {
            throw new RemoteException(GestorIdiomas.getMessage("error.gestorbbdd.bbdd"));
        }
        /** Capturamos excepción de carácter general*/
        catch (Exception exc) {
            throw new RemoteException(GestorIdiomas.getMessage("error.general"));
        }
        /** En cualquier caso ejecutaremos el siguiente código*/
        finally {
            try {
		resultSet.close();
                preparedStatement.close();
            }
            /** Capturamos excepción de carácter general*/
            catch (Exception exc) {
                throw new RemoteException(GestorIdiomas.getMessage("error.general"));
            }
        }

        return id_universidad;
    }
    
    /**
     * Método para obtener las Universidades
     * {pre: las universidades existen en el sistema}
     * {post: lista de Universidades}
     */
    public List<Universidad> getUniversidades() throws RemoteException{
        
        List<Universidad> lista = new ArrayList<Universidad>();
        String sqlString = null;
        PreparedStatement preparedStatement = null;
        ResultSet resultSet = null;

        try{
            //Establecemos la sentencia para obtener las universidades
            sqlString = "SELECT * "
                        + "FROM " + this.remoto.getSchema() + ".universidad "
                        + "ORDER BY nombre_universidad;";
            preparedStatement = this.remoto.getConexion().prepareStatement(sqlString);

            //Se ejecuta la sentencia y se establece el resulSet correspondiente
            resultSet = preparedStatement.executeQuery();

            //Si la consulta devuelve datos generaremos la instancia correspondiente que añadiremos a la lista
            while(resultSet.next()){
                Universidad universidad = new Universidad();
                universidad.setId_universidad(resultSet.getInt("id_universidad"));
		universidad.setNombre(resultSet.getString("nombre_universidad"));
                lista.add(universidad);
            }
        }
        /** Capturamos excepciones asociadas al acceso a la BBDD */
        catch (SQLException exc) {
            throw new RemoteException(GestorIdiomas.getMessage("error.gestorbbdd.bbdd"));
        }
        /** Capturamos excepciones de caracter general*/
        catch (Exception exc) {
            throw new RemoteException(GestorIdiomas.getMessage("error.general"));
        }
        /** En todo caso ejecutamos el siguiente codigo*/
        finally {
            //Cerramos las conexiones abiertas
            try {
		resultSet.close();
                preparedStatement.close();
            }
            /** Capturamos excepciones de caracter general*/
            catch (Exception exc) {
                throw new RemoteException(GestorIdiomas.getMessage("error.general"));
            }
        }

        //devolvemos la lista de universidades
        return lista;
    }
}
